/******************************************************************
*
*	CyberHTTP for Java
*
*	Copyright (C) Satoshi Konno 2002
*
*	File: HTTPStatus.java
*
*	Revision;
*
*	12/17/02
*		- first revision.
*	09/03/03
*		- Added CONTINUE_STATUS.
*	
******************************************************************/

package org.cybergarage.http;

import java.util.*;

import org.cybergarage.util.*;

public class HTTPStatus 
{
	////////////////////////////////////////////////
	//	Status codes. 
	////////////////////////////////////////////////
	
  // 100-199: Informational status codes
	public static final int CONTINUE = 100;
	public static final int SWITCHING_PROTOCOLS = 101;

  // 200-299: Success status codes
	public static final int OK = 200;
	public static final int CREATED = 201;
	public static final int ACCEPTED = 202;
	public static final int NON_AUTHORITATIVE_INFORMATION = 203;
	public static final int NO_CONTENT = 204;
	public static final int RESET_CONTENT = 205;
	public static final int PARTIAL_CONTENT = 206;

  // 400-499: Client error status codes
	public static final int BAD_REQUEST = 400;
	public static final int UNAUTHORIZED = 401;
	public static final int PAYMENT_REQUIRED = 402;
	public static final int FORBIDDEN = 403;
	public static final int NOT_FOUND = 404;
	public static final int METHOD_NOT_ALLOWED = 405;
	public static final int NOT_ACCEPTABLE = 406;
	public static final int PROXY_AUTHENTICATION_REQUIRED = 407;
	public static final int REQUEST_TIMEOUT = 408;
	public static final int CONFLICT = 409;
	public static final int GONE = 410;
	public static final int LENGTH_REQUIRED = 411;
	public static final int PRECONDITION_FAILED = 412;
	public static final int REQUEST_ENTITY_TOO_LARGE = 413;
	public static final int REQUEST_URI_TOO_LONG = 414;
	public static final int UNSUPPORTED_MEDIA_TYPE = 415;
	public static final int REQUESTED_RANGE_NOT_SATISFIABLE = 416;
	public static final int EXPECTATION_FAILED = 417;

  // 500-599: Server error status codes
	public static final int INTERNAL_SERVER_ERROR = 500;
	public static final int NOT_IMPLEMENTED = 501;
	public static final int BAD_GATEWAY = 502;
	public static final int SERVICE_UNAVAILABLE = 503;
	public static final int GATEWAY_TIMEOUT = 504;
	public static final int HTTP_VERSION_NOT_SUPPORTED = 505;

	public static final String code2String(int code)
	{
		switch (code)
    {
      //
      // List most-oft used once first (small optimization)
      //

      // 100's
      case CONTINUE: return "Continue";
      // 200's
      case OK: return "OK";
      // 400's
      case BAD_REQUEST: return "Bad Request";
      case NOT_FOUND: return "Not Found";
      case PRECONDITION_FAILED: return "Precondition Failed";
      // 500's
      case INTERNAL_SERVER_ERROR: return "Internal Server Error";

      //
      // Now the rarer ones
      //

      // 100's
      case SWITCHING_PROTOCOLS: return "Switching Protocols";
      // 200's
      case CREATED: return "Created";
      case ACCEPTED: return "Accepted";
      case NON_AUTHORITATIVE_INFORMATION: return "Non Authoritative Information";
      case NO_CONTENT: return "No Content";
      case RESET_CONTENT: return "Reset Content";
      case PARTIAL_CONTENT: return "Partial Content";
      // 400's
      case UNAUTHORIZED: return "Unauthorized";
      case PAYMENT_REQUIRED: return "Payment Required";
      case FORBIDDEN: return "Forbidden";
      case METHOD_NOT_ALLOWED: return "Method Not Allowed";
      case NOT_ACCEPTABLE: return "Not Acceptable";
      case PROXY_AUTHENTICATION_REQUIRED: return "Proxy Authentication Required";
      case REQUEST_TIMEOUT: return "Request Timeout";
      case CONFLICT: return "Conflict";
      case GONE: return "Gone";
      case LENGTH_REQUIRED: return "Length Required";
      case REQUEST_ENTITY_TOO_LARGE: return "Request Entity Too Large";
      case REQUEST_URI_TOO_LONG: return "Request URI Too Long";
      case UNSUPPORTED_MEDIA_TYPE: return "Unsupported Media Type";
      case REQUESTED_RANGE_NOT_SATISFIABLE: return "Requested Range Not Satisfiable";
      case EXPECTATION_FAILED: return "Expectation Failed";
      // 500's
      case NOT_IMPLEMENTED: return "Not Implemented";
      case BAD_GATEWAY: return "Bad Gateway";
      case SERVICE_UNAVAILABLE: return "Service Unavailable";
      case GATEWAY_TIMEOUT: return "Gateway Timeout";
      case HTTP_VERSION_NOT_SUPPORTED: return "HTTP Version Not Supported";

      default: return "Unknown Code (" + code + ")";
		}
	}
 	
	////////////////////////////////////////////////
	//	Constructor
	////////////////////////////////////////////////

	public HTTPStatus()
	{
		setVersion("");
		setStatusCode(0);
		setReasonPhrase("");
	}
	
	public HTTPStatus(String ver, int code, String reason)
	{
		setVersion(ver);
		setStatusCode(code);
		setReasonPhrase(reason);
	}

	public HTTPStatus(String lineStr)
	{
		set(lineStr);
	}
	
	////////////////////////////////////////////////
	//	Member
	////////////////////////////////////////////////

	private String version = "";
	private int statusCode = 0;
	private String reasonPhrase = "";

	public void setVersion(String value)
	{
		version = value;
	}
	
	public void setStatusCode(int value)
	{
		statusCode = value;
	}
	
	public void setReasonPhrase(String value)
	{
		reasonPhrase = value;
	}
	
	public String getVersion()
	{
		return version;
	}
	
	public int getStatusCode()
	{
		return statusCode;
	}
	
	public String getReasonPhrase()
	{
		return reasonPhrase;
	}

	public void set(String lineStr)
	{
		if (lineStr == null) {
			setVersion(HTTP.VERSION);
			setStatusCode(INTERNAL_SERVER_ERROR);
			setReasonPhrase(code2String(INTERNAL_SERVER_ERROR));
			return;
		}

		try {
			StringTokenizer st = new StringTokenizer(lineStr, HTTP.STATUS_LINE_DELIM);
		
			if (st.hasMoreTokens() == false)
				return;
			String ver = st.nextToken();
			if (st.hasMoreTokens() == false)
				return;
			String codeStr = st.nextToken();
			int code = 0;
			try {
				code = Integer.parseInt(codeStr);
			}
			catch (Exception e1) {}
			if (st.hasMoreTokens() == false)
				return;
			String reason = st.nextToken();
		
			setVersion(ver.trim());
			setStatusCode(code);
			setReasonPhrase(reason.trim());
		}
		catch (Exception e) {
			Debug.warning(e);
		}

	}
	
}
